home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-03 / dsbrowse.zip / QBASIC.ALL < prev   
Text File  |  1987-10-30  |  21KB  |  644 lines

  1. Microsoft Systems Journal
  2. Volume 2; Issue 4; September, 1987
  3.  
  4. Code Listings For:
  5.  
  6.     DSEARCH.ASM
  7.     DSEARCHT.BAS
  8.     BROWSE.BAS
  9.     pp. 63-76
  10.  
  11. Author(s): Dan Mick
  12. Title:     Microsoft QuickBASIC: Everyone's First PC Language Gets Better
  13.  
  14.  
  15.  
  16. Figure 1
  17. ========
  18.  
  19.  
  20.  
  21. ;;    DSEARCH.ASM
  22. ;;    Written by Dan Mick
  23.  
  24.  
  25.         page    62,132
  26.  
  27. data    segment public 'data'
  28. dta_ofs dw      ?               ;save area for BASIC's DTA
  29. dta_seg dw      ?
  30. fill    db      ?               ;"fill array" flag
  31. selflg  db      ?               ;"selective search" flag
  32. search_attr     db      ?       ;files' search attribute
  33. filcnt  dw      ?               ;count of files found
  34. path    db      64 dup (0)      ;search path, passed from BASIC
  35.  
  36. ;DTA structure for findfirst, findnext calls (see DOS documentation)
  37.  
  38. dta     db      21 dup (0)      ;reserved area (used for findnext)
  39. attrib  db      ?               ;attribute of file found
  40. time    dw      ?               ;time of last write
  41. date    dw      ?               ;date
  42. fsize   dd      ?               ;filesize (32 bit integer)
  43. fname   db      13 dup (0)      ;ASCIIZ filename: name.ext,00
  44. data    ends
  45.  
  46. dgroup  group   data
  47.  
  48. code    segment byte public 'code'
  49.         assume  cs:code, ds:dgroup
  50.         .xlist
  51. ;
  52. ;CALL DSEARCH(path$, attr, count, selective, array ofs)
  53. ; path$ is a normal string variable with the path for the
  54. ; directory search.  It be a full pathname, including filename
  55. ; and extension fields.  To get all the files in the default
  56. ; directory on C:, for instance, path$="C:*.*", or all the files
  57. ; in subdir on the current drive, path$="subdir\*.*".
  58. ; attr is the MS-DOS file attribute for the search.  See below for
  59. ; a description.  Each bit represents a file attribute.
  60. ; count is an input and an output parameter.  On input, if it is
  61. ; zero, the files will not be put in the array, only counted.
  62. ; This is provided so that a dynamic array may be allocated after
  63. ; the size is determined by dsearch().  If count is non-zero on
  64. ; input, the filenames will be placed in the array.
  65. ; In either case, the count of filenames found is returned.
  66. ; selective is a flag indicating how to do the counting and
  67. ; searching process.  If the file attribute 10 is specified, for
  68. ; example, DOS will return all those filenames that have the
  69. ; subdir attribute as well as those that don't.  If selective is
  70. ; set nonzero, the non-subdir files will not be returned.  What
  71. ; this does, basically, is allow a "filter normal files" selection
  72. ; so that subdirs and volume labels may easily be found.
  73. ; array offset is a pointer (offset only for strings) to a string
  74. ; array big enough to hold all files found in path$.  The size
  75. ; required may be determined as described below.
  76. ;
  77. ; The attribute byte:
  78. ;
  79. ;           -------------------------------------
  80. ;           | X | X | X | A | D | V | S | H | R |
  81. ;           -------------------------------------
  82. ;
  83. ;  X is don't care, A = archive, D = subdirectory, V = volume label,
  84. ;  S = system, H = hidden, R = read-only.
  85. ;
  86.         .list
  87.  
  88. stk     struc
  89. bbp     dw      ?               ;BASIC's bp
  90. retadd  dd      ?               ;return address
  91. arrofs  dw      ?               ;param: array offset
  92. select  dw      ?               ;param: filter normal files flag
  93. count   dw      ?               ;param: count flag/count return
  94. attr    dw      ?               ;param: search attr
  95. path$   dw      ?               ;param: pathname to search
  96. stk     ends
  97.  
  98. ;calculate value to pop with RET n at end of proc (length of params)
  99. popval  =       (offset path$) + (size path$) - (offset arrofs)
  100.  
  101. strdes  struc                   ;BASIC string descriptor structure
  102. len     dw      ?               ;word length of string
  103. strptr  dw      ?               ;pointer to string space
  104. strdes  ends
  105.  
  106. dsearch proc    far             ;it's a far proc to BASIC
  107.         public  dsearch         ;let LINK know about this one
  108.  
  109.         push    bp              ;save BASIC's bp
  110.         mov     bp,sp           ;address stack as it exists now
  111.  
  112.         mov     [filcnt],0      ;initialize file count
  113.  
  114.         mov     si,path$[bp]    ;get pointer to string descriptor
  115.         mov     cx,len[si]      ;cx = path length
  116.         mov     si,strptr[si]   ;si -> path string data
  117.         lea     di,path         ;di -> place to fill
  118.         rep     movsb           ;move pathname to our data area
  119.         mov     byte ptr es:[di],0 ;make sure it's an ASCIIZ string
  120.  
  121.         mov     si,count[bp]    ;get pointer to fill flag in di
  122.         mov     cx,[si]         ;cx = fill flag
  123.         mov     byte ptr [fill],0 ;set flag to "no" first
  124.         or      cx,cx           ;nonzero?
  125.         jz      nofill          ;nope
  126.         mov     byte ptr [fill],0ffh ;yes, set flag
  127.  
  128. nofill: mov     di,select[bp]   ;get pointer to selective flag in di
  129.         mov     cx,[di]         ;cx = selective flag
  130.         mov     byte ptr [selflg],0 ;set flag to "no" first
  131.         or      cx,cx           ;nonzero?
  132.         jz      nosel           ;nope
  133.         mov     byte ptr [selflg],0ffh ;yes, set flag
  134.  
  135. nosel:  mov     di,attr[bp]     ;point at search attribute param
  136.         mov     cx,[di]         ;and get it
  137.  
  138.         mov     ah,2fh          ;get BASIC's DTA
  139.         int     21h
  140.         mov     [dta_ofs],bx
  141.         mov     [dta_seg],es    ;and save it
  142.         lea     dx,dta          ;set DTA to our area here
  143.         mov     ah,1ah
  144.         int     21h
  145.  
  146.         mov     di,arrofs[bp]   ;di -> first string descriptor
  147.         mov     di,[di]         ;di = first string descriptor offset
  148.         mov     bx,ds           ;set up es to string array segment
  149.         mov     es,bx           ; (BASIC's data segment)
  150.                                 ;now es:di -> first string descriptor
  151.  
  152.         mov     ah,4eh          ;find first matching file
  153.         xor     ch,ch           ;clear hi part of attribute
  154.         lea     dx,path         ;ds:dx points to search path
  155.         int     21h
  156.         jnc     ok              ;if error, cy set
  157.         cmp     ax,18           ;no files found?
  158.         jz      exit            ;yes, don't report error
  159.         mov     [filcnt],0ffffh ;set count to -1 to report path error
  160.         jmp     short exit      ;and leave
  161.  
  162. ok:     call    countit         ;rets cy if should save, incs filcnt
  163.         jz      findnext        ;no fill if zr set
  164.         call    move_filename   ;do the move
  165.  
  166. findnext:
  167.         mov     ah,4fh          ;find next function
  168.         int     21h             ;do it
  169.         jc      exit            ;if error, must be no more files
  170.         call    countit         ;count, return cy if should save
  171.         jz      findnext        ;if zr set, don't save name
  172.         call    move_filename   ;move it
  173.         jmp     short findnext  ;and keep hunting
  174.  
  175. exit:   push    ds
  176.         lds     dx,dword ptr [dta_ofs] ;get BASIC's DTA
  177.         mov     ah,1ah                 ;set DTA fn.
  178.         int     21h
  179.         pop     ds
  180.         mov     di,count[bp]    ;di -> fattr for count return
  181.         mov     ax,[filcnt]     ;get file count
  182.         mov     [di],ax         ;put file count in fattr
  183.         pop     bp              ;restore BASIC's BP
  184.         ret     popval          ;return and pop parameter pointers
  185. dsearch endp
  186.  
  187. countit         proc
  188. ;
  189.  
  190. ;Check file attribute if selective, and update count or not based on
  191. ;result. Return flag saying whether or not to move filename, too,
  192. ;based on updated count and the "fill" flag.
  193.  
  194. ;
  195.          cmp     [selflg],0ffh  ;are we selective?
  196.          jnz     bump           ;nope, count it
  197.          cmp     [attrib],cl    ;is the attr just what we want?
  198.          je      bump           ;yes, count this file
  199.          cmp     cl,cl          ;nope, set ZF
  200.          jmp     short dontfill ;and skip to exit
  201. bump:    inc     [filcnt]       ;update counter
  202.          cmp     [fill],0       ;now, are we filling?
  203. dontfill:                       ;get here from jne, so NZ
  204.          ret                    ; return with NZ if filling
  205. countit         endp
  206.  
  207. move_filename   proc    near
  208. ;
  209. ;es:di points to string descriptor to fill with filename from DTA
  210. ;
  211.         push    di              ;save pointer to descr. length part
  212.         mov     di,es:strptr[di] ;and point instead to string data
  213.         lea     si,fname        ;si -> filename (ASCIIZ)
  214. moveloop:
  215.         lodsb                   ;get filename character
  216.         or      al,al           ;is it 0? (end of string?)
  217.         jz      done            ;yes, quit moving data
  218.         stosb                   ;no, store
  219.         jmp     short moveloop  ;and continue
  220. done:   test    byte ptr [attrib],10h ;is this a subdir?
  221.         jz      notsub          ;no
  222.         mov     al,'\'          ;yes, store a trailing backslash
  223.         stosb
  224. notsub: pop     di              ;di -> length in s.d. again
  225.         add     di,4            ;move to next s.d. pointer
  226.         ret
  227. move_filename   endp
  228.  
  229. code    ends
  230.         end     dsearch
  231.  
  232.  
  233.  
  234.  
  235.  
  236. Figure 2
  237. ========
  238.  
  239.  
  240. "Test Program" for DSEARCH.
  241.  
  242.  
  243. 'dsearcht.bas
  244. 'simple program to check dsearch routine and make sure it's
  245. 'working.  The idea is to call it just enough to check out
  246. 'its capabilities, and perhaps vary its input by small
  247. 'amounts, so that you get a controlled test where there are
  248. 'no likely bugs in the BASIC code.
  249.  
  250.  
  251. rem $dynamic
  252. DIM A$(0)
  253.  
  254. start:
  255. input "Path for directory? (wildcards allowed): ",path$
  256. if instr("\:",right$(path$,1)) then path$=path$+"*.*"
  257.  
  258. 'get number of filenames in path
  259. attr%=&H10:arrofs%=0:count%=0:selective%=0
  260. call dsearch(path$,attr%,count%,selective%,arrofs%)
  261.  
  262. 'now count% has actual filename count for redim, or -1 if error
  263. '(other than file not found, that is.)
  264.  
  265. if count%=-1 then print "Bad pathname":goto start
  266. redim a$(count%)
  267.  
  268. print "There are "count%"filenames in path "path$"."
  269. 'set up a$ so that dsearch doesn't have to change length
  270. for i=0 to count%-1:a$(i)=space$(12):next i
  271.  
  272. arrptr=varptr(a$(0))
  273. arrofs%=int(arrptr)             'explicit conversion
  274.  
  275. call dsearch(path$,attr%,count%,selective%,arrofs%)
  276.  
  277. for i= 0 to count%-1:print i;":";a$(i):next i
  278. goto start
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286. Figure 3
  287. ========
  288.  
  289.  
  290.  
  291. BROWSE.BAS
  292.  
  293.  
  294. 'BROWSE.BAS - a file browser/directory maintenance routine
  295. 'To compile in the editor environment, make a user library by
  296. 'assembling DSEARCH.ASM, using BUILDLIB to add it and USERLIB.OBJ
  297. 'to a user library (call it MYLIB.EXE, for instance), and then
  298. 'use the /L switch to load QB, as in "QB BROWSE /L MYLIB.EXE".
  299. 'To compile standalone, use "LINK BROWSE+DSEARCH+USERLIB...."
  300.  
  301. defint a-z
  302. dim winrec(8) 'holds window dimensions, colors for text and borders
  303.  
  304. 'the following arrays and constants are used for int86()
  305. dim inary(7), outary(7)
  306. const ax = 0, bx = 1, cx = 2, dx = 3
  307. const bp = 4, si = 5, di = 6, flag = 7
  308.  
  309. 'actions returned by PageAndSelect
  310. const disk.change = 1, delete.file = 2, type.file = 3, quit = 4
  311. action.flag = 0  'set by PageAndSelect to one of the above
  312.  
  313. rem $dynamic
  314. dim filename$(0)
  315. dim shared ScreenData (0,0)
  316.  
  317. def fn.min(x,y)
  318.    if x < y then fn.min = x else fn.min = y
  319. end def
  320.  
  321. def fn.max(x,y)
  322.    if x > y then fn.max = x else fn.max = y
  323. end def
  324.  
  325. '************************ MAIN PROGRAM **************************
  326.  
  327. call GetCurrDisk(origdisk$)
  328. call GetCurrPath(origdisk$,origpath$)
  329.  
  330. disk$ = origdisk$
  331.  
  332. 'get a count of all normal and subdir files
  333.  
  334. Do
  335.    call GetCurrPath(disk$,CurrPath$)
  336.    searchpath$ = disk$ + ":" + CurrPath$ + "*.*"
  337.  
  338.    attr = &H10 : count  =  0 : selective = 0
  339.    arrofs = int(varptr(filename$(0)))
  340.    call dsearch (searchpath$,attr,count,selective,arrofs)
  341.  
  342.    ' This should never happen!...
  343.    if count = -1 then
  344.       locate 25,1:print "Invalid path: "searchpath$
  345.       print "Strike a key...":a$ = input$(1):end
  346.    end if
  347.  
  348.    redim filename$(count-1)
  349.    for i = 0 to count-1:filename$(i) = space$(12):next i
  350.  
  351.    arrofs = int(varptr(filename$(0)))
  352.    call dsearch (searchpath$,attr,count,selective,arrofs)
  353.  
  354.    'now filename$(0 to count-1) have all the files and subdirs
  355.    winrec(1) = 1 : winrec(2) = 1    'upper left of window  (row,col)
  356.    winrec(3) = 10 : winrec(4) = 80   'lower right of window
  357.    winrec(5) = 0 : winrec(6) = 11    'fg/bg color
  358.    winrec(7) = 10 : winrec(8) = 0    'border colors, fg/bg
  359.  
  360.    call makewindow (winrec())
  361.  
  362.    'do window/cursor/path manipulation.
  363.  
  364.    call PageAndSelect(winrec(),filename$(),action.flag,f$)
  365.  
  366.    'f$ comes back as fixed-length (12) string
  367.    ' ...strip off trailing blanks
  368.    i = instr(f$," ") : if i > 0 then f$ = left$(f$,i-1)
  369.  
  370.    select case action.flag
  371.       case quit
  372.          call SetCurrDisk(OrigDisk$)
  373.          call SetCurrPath(OrigPath$)
  374.          cls : end
  375.       case disk.change
  376.          cls : print "Enter new disk drive letter: ";
  377.          disk$ = input$(1) : print disk$;
  378.          if disk$ > "Z" then disk$ = chr$(asc(disk$) and &HDF)
  379.          call SetCurrDisk(disk$)
  380.          action.flag = 0
  381.       case type.file
  382.          if right$(f$,1) = "\" then
  383.             CurrPath$ = CurrPath$ + f$
  384.             call SetCurrPath(CurrPath$)
  385.          else
  386.             call ListIt (disk$+":"+CurrPath$+f$)
  387.          end if
  388.       case delete.file
  389.          kill (disk$+":"+CurrPath$+f$)
  390.    end select
  391.  
  392.    action.flag = 0
  393. loop while (1)
  394.  
  395. '****************************************************************
  396.  
  397. sub makewindow (winrec(1)) static
  398. y1 = winrec(1):x1 = winrec(2):y2 = winrec(3):x2 = winrec(4)
  399. fc = winrec(5):bc = winrec(6):bfc = winrec(7):bbc = winrec(8)
  400. wid  =  x2-x1+1 : height = y2-y1+1
  401.  
  402. const vert = 186,upright = 187,lowright = 188
  403. const lowleft = 200,upleft = 201,horiz = 205
  404.  
  405. color bfc,bbc
  406. locate y1,x1:print chr$(upleft);string$(wid-2,horiz);chr$(upright);
  407. for i = 2 to height-1
  408.    locate y1+i-1,x1:print chr$(vert);
  409.    locate y1+i-1,x2:print chr$(vert);
  410. next i
  411. locate y2,x1:print chr$(lowleft);string$(wid-2,horiz);chr$(lowright);
  412.  
  413. call clearwindow(winrec())
  414. end sub
  415.  
  416. '****************************************************************
  417.  
  418. sub clearwindow (winrec(1)) static
  419. y1 = winrec(1):x1 = winrec(2):y2 = winrec(3):x2 = winrec(4)
  420. fc = winrec(5):bc = winrec(6):bfc = winrec(7):bbc = winrec(8)
  421. wid  =  x2-x1+1 : height = y2-y1+1
  422.  
  423. color fc,bc
  424. for i = 2 to height-1
  425.    locate y1+i-1,x1+1:print string$(wid-2," ");
  426. next i
  427. end sub
  428.  
  429. '****************************************************************
  430.  
  431. sub savewindow (winrec(1)) static
  432. y1 = winrec(1):x1 = winrec(2):y2 = winrec(3):x2 = winrec(4)
  433. fc = winrec(5):bc = winrec(6):bfc = winrec(7):bbc = winrec(8)
  434. wid = x2-x1+1 : height = y2-y1+1
  435.  
  436. for i = x1 to x2
  437.    for j = y1 to y2
  438.       ScreenData(j-y1,i-x1) = screen(j,i,1) * 256 + screen (j,i,0)
  439.    next j
  440. next i
  441. end sub
  442.  
  443. '****************************************************************
  444.  
  445. sub restorewindow (winrec(1)) static
  446. y1 = winrec(1):x1 = winrec(2):y2 = winrec(3):x2 = winrec(4)
  447. fc = winrec(5):bc = winrec(6):bfc = winrec(7):bbc = winrec(8)
  448.  
  449. for j = y1 to y2
  450.    locate j,x1
  451.    for i = x1 to x2
  452.       d = ScreenData(j-y1,i-x1)
  453.       bc = (d\256)\8 : fc = (d\256) mod 8 : color fc,bc
  454.       print chr$(d and &hff);
  455.    next i
  456. next j
  457. end sub
  458.  
  459. '****************************************************************
  460.  
  461. sub PageAndSelect_
  462.   (winrec(1),file$(1),action.flag,FileSelected$) static
  463.  
  464. 'This routine does all the work here.  It assumes MakeWindow
  465. 'has been called before entering, and does all key processing and
  466. 'subsequent window updates.  action.flag is returned as the action
  467. 'for the main program to take (see the constants in the main program
  468. 'for a list of possible actions).
  469.  
  470. shared disk$,CurrPath$,count
  471.  
  472. 'second codes from extended keys used in PageAndSelect
  473. const up = 72, down = 80, left = 75, right = 77
  474. const f1 = 59, AltD = 32, AltX = 45
  475.  
  476. y1 = winrec(1):x1 = winrec(2):y2 = winrec(3):x2 = winrec(4)
  477. fc = winrec(5):bc = winrec(6):bfc = winrec(7):bbc = winrec(8)
  478. wid = x2-x1+1 : height = y2-y1+1
  479.  
  480. locate y1,x1+1:color bfc,bbc:print " ";disk$;":";CurrPath$;" "
  481. locate y2,x1+1
  482. print "RET-Type file  AltD - delete file  F1 - chg disk  AltX - quit"
  483. locate y1,x2-1-9:print count;"files"
  484.  
  485. NamesPerLine = (wid-2)\15 'how many filenames on each line in window
  486. lines = height-2          'how many usable lines inside window
  487. FilesPerWindow = lines * NamesPerLine
  488.  
  489. StartIndex = 0 'first file$() to be displayed in window
  490. CurrIndex = 0  'current file$() being highlighted
  491. NewIndex = 0   'updated file$() index after moving cursor
  492.  
  493. do
  494.    call clearwindow(winrec())
  495.    limit = fn.min (ubound(file$) - StartIndex, FilesPerWindow - 1)
  496.    color fc,bc : locate y1+1
  497.    for i = 0 to limit step NamesPerLine
  498.       for j = 0 to NamesPerLine-1
  499.          locate ,x1 + 1 + j*15
  500.          if StartIndex + i + j <= ubound(file$) then
  501.             print file$(StartIndex+i+j);
  502.          else
  503.             print space$(15);
  504.          end if
  505.       next j
  506.    print
  507.    next i
  508.  
  509.    'initialize highlight bar position
  510.    BarRow = y1+1 : BarCol = x1 + 1
  511.  
  512.    do
  513.       color fc,bc : locate BarRow,BarCol : print file$(CurrIndex);
  514.       CurrIndex = NewIndex
  515.       BarRow = (CurrIndex-StartIndex)\NamesPerLine + y1 + 1
  516.       BarCol = (CurrIndex mod NamesPerLine)*15 + x1 + 1
  517.       color bc,fc : locate BarRow,BarCol : print file$(CurrIndex);
  518.  
  519.       'wait for extended character (look for cursor keys) or RETURN
  520.       GetKey:
  521.          a$ = "" : while a$ = "" : a$ = inkey$ : wend
  522.          if a$ = chr$(13) then
  523.             action.flag = type.file
  524.             FileSelected$ = file$(CurrIndex)
  525.             exit do
  526.          end if
  527.       if len(a$)<>2 then goto GetKey
  528.  
  529.       redraw = 0  'flag to indicate when window must be redrawn
  530.                   'and in which direction the cursor was moving
  531.       select case asc(right$(a$,1))
  532.          case up
  533.             NewIndex = fn.max (0,CurrIndex-NamesPerLine)
  534.             if NewIndex < StartIndex then redraw = -1
  535.          case down
  536.             NewIndex = fn.min (ubound(file$), CurrIndex+NamesPerLine)
  537.             if NewIndex > StartIndex + FilesPerWindow - 1 _
  538.              then redraw = 1
  539.          case left
  540.             NewIndex = fn.max (0,CurrIndex-1)
  541.             if NewIndex < StartIndex then redraw = -1
  542.          case right
  543.             NewIndex = fn.min (ubound(file$), CurrIndex + 1)
  544.             if NewIndex > StartIndex + FilesPerWindow - 1 _
  545.              then redraw = 1
  546.  
  547.          case f1
  548.             action.flag = disk.change : file.selected = -1 : exit do
  549.          case AltX
  550.             action.flag = quit : file.selected = -1 : exit do
  551.          case AltD
  552.             action.flag = delete.file
  553.             FileSelected$ = file$(CurrIndex) : exit do
  554.          case else
  555.             sound 440,2:sound 220,2
  556.       end select
  557.    loop while redraw = 0
  558.  
  559.    if action.flag then exit do
  560.    'otherwise, fall through and redo the entire "do" loop
  561.    select case sgn(redraw)
  562.       case -1
  563.         StartIndex = fn.max (StartIndex - FilesPerWindow , 0)
  564.       case 1
  565.         StartIndex = fn.min (StartIndex + FilesPerWindow , _
  566.                              ubound(file$))
  567.    end select
  568.    CurrIndex = StartIndex
  569. loop while not action.flag
  570.  
  571. end sub
  572.  
  573. '****************************************************************
  574.  
  575. sub     GetCurrPath(disk$,CurrPath$) static
  576. shared inary(),outary()
  577.  
  578. 'first set up 64-byte work area for Int 21h Function 47h
  579. ' (get current directory)
  580. CurrPath$ = space$(64) : pathptr = sadd(CurrPath$)
  581.  
  582. inary(dx)=asc(disk$)-65+1
  583. inary(si)=pathptr 'pointer to area to fill
  584. inary(ax)=&H4700  'function number
  585. call int86(&H21,varptr(inary(0)),varptr(outary(0)))
  586.  
  587. 'strip off trailing NUL, rest of blanks
  588. CurrPath$=left$(CurrPath$,instr(CurrPath$,chr$(0))-1)
  589. CurrPath$="\"+CurrPath$
  590. if CurrPath$ <> "\" then CurrPath$=CurrPath$+"\"
  591. end sub
  592.  
  593. '****************************************************************
  594.  
  595. sub GetCurrDisk(disk$) static
  596. shared inary(),outary()
  597. inary(ax) = &H1900
  598. call int86(&H21,varptr(inary(0)),varptr(outary(0)))
  599. disk$ = chr$(65 + (outary(ax) and 255))
  600. end sub
  601.  
  602. '****************************************************************
  603.  
  604. sub SetCurrDisk(disk$) static
  605. shared inary(),outary()
  606.  
  607. inary(ax) = &H0E00
  608. inary(dx) = asc(disk$) - 65
  609. call int86(&H21,varptr(inary(0)),varptr(outary(0)))
  610.  
  611. end sub
  612.  
  613. '****************************************************************
  614.  
  615. sub SetCurrPath(path$) static
  616. shared inary(),outary()
  617.  
  618. newpath$=path$
  619. if newpath$<>"\" then newpath$=left$(newpath$,len(newpath$)-1)
  620. newpath$=newpath$+chr$(0)
  621.  
  622. inary(ax) = &H3B00
  623. inary(dx) = sadd(newpath$)
  624. call int86(&H21,varptr(inary(0)),varptr(outary(0)))
  625.  
  626. end sub
  627.  
  628. '****************************************************************
  629.  
  630. sub TypeIt (path$) static
  631.    cls
  632.    shell ("type "+path$+" | more")
  633.    locate 25,1:print "Any key to continue...";
  634.    a$=input$(1):cls
  635. end sub
  636.  
  637. '****************************************************************
  638.  
  639. sub ListIt (path$) static
  640.    shell ("list "+path$)
  641.    cls
  642. end sub
  643.  
  644.